using System.Collections.Generic;
using System.IO;
using System.Linq;
using NpcFramework;
using UnityEditor;
using UnityEngine;

namespace Yoozoo.Gameplay.Liberty.AI
{
    public class TrafficSystemHolder : MonoBehaviour
    {
        public string configName = "libertyTrafficData";
        public string scenePrefix = "";
        public Transform carPathHolder;
        public Transform npcPathHolder;
        public Transform trafficLightHolder;
        
        public void Export()
        {
            ExportData(configName,carPathHolder,npcPathHolder,trafficLightHolder);
        }
        
        public string PATH_HEADER = "Assets/ResourcesAssets/Hanging/Traffic";
        private static LibertyTrafficData _trafficData;
        private void ExportData(string configName,
            Transform carPathHolder,
            Transform npcPathHolder,
            Transform trafficLightHolder)
        {
            #if UNITY_EDITOR
            ReCreateDir(PATH_HEADER);
            AssetDatabase.Refresh();
            
            string configPath = PATH_HEADER + "/" +configName + ".asset";
            _trafficData = AssetDatabase.LoadAssetAtPath<ScriptableObject>(configPath) as LibertyTrafficData;
            if (!_trafficData)
            {
                _trafficData = ScriptableObject.CreateInstance<LibertyTrafficData>();
                AssetDatabase.CreateAsset(_trafficData,configPath);
            }

            _trafficData.trafficLights = new List<TrafficLightData>();
            _trafficData.npcPathList = new List<PathData>();
            _trafficData.carPathList = new List<PathData>();


            /*
            
            List<TrafficLightController> trafficLightControllers = trafficLightHolder.GetComponentsInChildren<TrafficLightController>().ToList();
            // 导出红绿灯和其中的Npc路径

            List<PathData> lightPaths = new List<PathData>();

            foreach (var lightController in trafficLightControllers)
            {
                int lightId = lightController.trafficLightId;

                for (int i = 0; i < lightController.lightPaths.Count; i++)
                {
                    NpcWayPath path = lightController.lightPaths[i];
                    path.WayID = lightId * 1000 + i;

                    PathData pathData = new PathData();

                    pathData.id = path.WayID;
                    pathData.loop = path.IsLoop;
                    pathData.pathType = PathType.TrafficLight;

                    pathData.pathPoints = new List<PathPointData>(50);

                    for (int j = 0; j < path.WayPoints.Count; j++)
                    {
                        pathData.pathPoints.Add(GetPointData(path.WayPoints[j],PathPointType.TrafficLight,lightId));
                    }
                    
                    lightPaths.Add(pathData);
                }
                
                // 红绿灯保存Prefab
                string lightPath = "";
                
                
                TrafficLightData lightData = new TrafficLightData();
                lightData.lightId = lightId;
                lightData.resPath = lightPath;
                _trafficData.trafficLights.Add(lightData);
            }
            */

            // 导出Npc路径信息

            List<NpcWayPath> npcWayPaths = npcPathHolder.GetComponentsInChildren<NpcWayPath>().ToList();

            List<string> prefabPathList = new List<string>();
            List<GameObject> prefabInstanceList = new List<GameObject>();

            for (int i = 0; i < npcWayPaths.Count; i++)
            {
                NpcWayPath path = npcWayPaths[i];
                PathData pathData = new PathData();
                
                GameObject pathObject = GameObject.Instantiate(path.gameObject);
                string pathName = scenePrefix + "NpcPath_" + path.WayID.ToString();
                string assetPath = PATH_HEADER + "/" + pathName + ".prefab";

                pathData.id = path.WayID;
                pathData.loop = path.IsLoop;
                pathData.pathType = PathType.Npc;

                pathData.pathPoints = new List<PathPointData>(50);

                for (int j = 0; j < path.WayPoints.Count; j++)
                {
                    pathData.pathPoints.Add(GetPointData(path.WayPoints[j],PathPointType.Normal,PathType.Npc));
                }

                pathData.prefabPath = assetPath;
                pathData.position = path.transform.position;
                
                _trafficData.npcPathList.Add(pathData);
                
                prefabPathList.Add(assetPath);
                prefabInstanceList.Add(pathObject);
            }
            

            // TODO 遍历每个Npc路点会与红绿灯路径尝试链接
            
            
            
            // 导出车辆路径
            List<NpcWayPath> carWayPaths = carPathHolder.GetComponentsInChildren<NpcWayPath>().ToList();

            for (int i = 0; i < carWayPaths.Count; i++)
            {
                NpcWayPath path = carWayPaths[i];
                PathData pathData = new PathData();
                
                GameObject pathObject = GameObject.Instantiate(path.gameObject);
                string pathName = scenePrefix + "NpcPath_" + path.WayID.ToString();
                string assetPath = PATH_HEADER + "/" + pathName + ".prefab";

                pathData.id = path.WayID;
                pathData.loop = path.IsLoop;
                pathData.pathType = PathType.Car;

                pathData.pathPoints = new List<PathPointData>(50);

                for (int j = 0; j < path.WayPoints.Count; j++)
                {
                    pathData.pathPoints.Add(GetPointData(path.WayPoints[j],PathPointType.Normal,PathType.Car));
                }

                pathData.prefabPath = assetPath;
                pathData.position = path.transform.position;
                
                _trafficData.carPathList.Add(pathData);
                
                prefabPathList.Add(assetPath);
                prefabInstanceList.Add(pathObject);
            }
            
            
            
            EditorUtility.SetDirty(_trafficData);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();

            for (int i = 0; i < prefabPathList.Count; i++)
            {
                string path = prefabPathList[i];
                GameObject o = prefabInstanceList[i];
                
                EditorUtility.SetDirty(o);
                PrefabUtility.SaveAsPrefabAsset(o, path);
                AssetDatabase.Refresh();
                
                GameObject.DestroyImmediate(o);
            }
            EditorUtility.DisplayDialog("成功", "导出交通系统数据成功 ^_^", "OK");
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
#endif
        }
        
        private static void ReCreateDir(string path)
        {
            DeleteDir(Application.dataPath.Replace("Assets", "") + path, true);
            Directory.CreateDirectory(Application.dataPath.Replace("Assets", "") + path);
        }

        private static void DeleteDir(string path, bool deleteOwner)
        {
            if (path.Trim() == "" || !Directory.Exists(path)) return;
            DirectoryInfo dirInfo = new DirectoryInfo(path);
            FileInfo[] fileInfos = dirInfo.GetFiles();
            if (fileInfos != null && fileInfos.Length > 0)
            {
                foreach (FileInfo fileInfo in fileInfos)
                {
                    File.Delete(fileInfo.FullName);
                }
            }
            DirectoryInfo[] dirInfos = dirInfo.GetDirectories();
            if (dirInfos != null && dirInfos.Length > 0)
            {
                foreach (DirectoryInfo childDirInfo in dirInfos)
                {
                    DeleteDir(childDirInfo.FullName, true);
                }
            }
            if (deleteOwner)
            {
                Directory.Delete(dirInfo.FullName, true);
            }
        }
        public static PathPointData GetPointData(NpcWayPoint wayPoint,PathPointType pointType,PathType pathType,
            int param0 = 0,int param1 = 0,int param2 = 0)
        {
            PathPointData pointData = new PathPointData();

			if(wayPoint.WayPath == null){
				Debug.LogError("get point data failed",wayPoint.gameObject);
			}
            pointData.pathId = wayPoint.WayPath.WayID;
            pointData.pointIndex = wayPoint.Index;
            pointData.prevIndex = wayPoint.PrevWayPoint.Index;
            pointData.nextIndex = wayPoint.NextWayPoint.Index;
            //pointData.nextPaths

            pointData.position = wayPoint.transform.position;
            pointData.forward = wayPoint.transform.forward;
            pointData.right = wayPoint.transform.right;

            pointData.width = wayPoint.width;
            pointData.pathType = pathType;
            pointData.pointType = pointType;

            pointData.param0 = param0;
            pointData.param1 = param1;
            pointData.param2 = param2;
            
            return pointData;
        }
        
    }
}